package com.andy.base.utils

import android.content.Context
import android.content.SharedPreferences
import com.andy.base.AppHelper
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method

/**
 * Author:Andy
 * Date:2023/3/21 10:55
 * Description:SpUtils
 */

object SPUtils {
    /**
     * 保存在手机里面的文件名
     */
    private const val FILE_NAME = "share_avatar_data"

    private fun getSP(): SharedPreferences {
        return AppHelper.mContext.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
    }

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     * @param key
     * @param any
     */
    fun put(key: String, any: Any) {
        if (key.isEmpty()) {
            return
        }
        val editor = getSP().edit()
        when (any) {
            is String -> {
                editor.putString(key, any)
            }
            is Int -> {
                editor.putInt(key, any)
            }
            is Boolean -> {
                editor.putBoolean(key, any)
            }
            is Float -> {
                editor.putFloat(key, any)
            }
            is Long -> {
                editor.putLong(key, any)
            }
            else -> {
                editor.putString(key, any.toString())
            }
        }
        apply(editor)
    }

    /**
     * @param key
     * @return String
     */
    fun getString(key: String): String? {
        if (key.isEmpty()) {
            return null
        }
        return getSP().getString(key, null)
    }

    /**
     * @param key
     * @param default
     * @return String
     */
    fun getString(key: String, default: String): String? {
        if (key.isEmpty()) {
            return null
        }
        return getSP().getString(key, default)
    }

    /**
     * @param key
     * @return Boolean
     */
    fun getBoolean(key: String): Boolean? {
        if (key.isEmpty()) {
            return null
        }
        return getSP().getBoolean(key, false)
    }

    /**
     * @param key
     * @param default
     * @return Boolean
     */
    fun getBoolean(key: String, default: Boolean): Boolean? {
        if (key.isEmpty()) {
            return null
        }
        return getSP().getBoolean(key, default)
    }

    /**
     * @param key
     * @return Int
     */
    fun getInt(key: String): Int? {
        if (key.isEmpty()) {
            return null
        }
        return getSP().getInt(key, 0)
    }

    /**
     * @param key
     * @param default
     * @return Int
     */
    fun getInt(key: String, default: Int): Int? {
        if (key.isEmpty()) {
            return null
        }
        return getSP().getInt(key, default)
    }

    /**
     * @param key
     * @return Long
     */
    fun getLong(key: String): Long? {
        if (key.isEmpty()) {
            return null
        }
        return getSP().getLong(key, 0L)
    }

    /**
     * @param key
     * @param default
     * @return Long
     */
    fun getLong(key: String, default: Long): Long? {
        if (key.isEmpty()) {
            return null
        }
        return getSP().getLong(key, default)
    }

    /**
     * @param key
     * @return Float
     */
    fun getFloat(key: String): Float? {
        if (key.isEmpty()) {
            return null
        }
        return getSP().getFloat(key, 0F)
    }

    /**
     * @param key
     * @param default
     * @return Float
     */
    fun getFloat(key: String, default: Float): Float? {
        if (key.isEmpty()) {
            return null
        }
        return getSP().getFloat(key, default)
    }

    /**
     * 移除某个key值已经对应的值
     *
     * @param key
     */
    fun remove(key: String?) {
        val editor = getSP().edit()
        editor.remove(key)
        apply(editor)
    }

    /**
     * 清除所有数据
     */
    fun clear() {
        val editor = getSP().edit()
        editor.clear()
        apply(editor)
    }

    /**
     * 查询某个key是否已经存在
     * @param key
     * @return
     */
    fun contains(key: String?): Boolean {
        return getSP().contains(key)
    }

    /**
     * 返回所有的键值对
     * @return
     */
    fun getAll(): Map<String, *> {
        return getSP().all
    }

    /**
     * 如果找到则使用apply执行，否则使用commit
     * @param editor
     */
    private fun apply(editor: SharedPreferences.Editor) {
        try {
            val sApplyMethod = findApplyMethod()
            if (sApplyMethod != null) {
                sApplyMethod.invoke(editor)
                return
            }
        } catch (e: IllegalArgumentException) {
            e.printStackTrace()
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
        } catch (e: InvocationTargetException) {
            e.printStackTrace()
        }
        editor.commit()
    }

    /**
     * 反射查找apply的方法
     *
     * @return
     */
    private fun findApplyMethod(): Method? {
        try {
            val clz: Class<*> = SharedPreferences.Editor::class.java
            return clz.getMethod("apply")
        } catch (e: NoSuchMethodException) {
            e.printStackTrace()
        }
        return null
    }
}